/*
Copyright [2020] [https://www.xiaonuo.vip]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：

1.请不要删除和修改根目录下的LICENSE文件。
2.请不要删除和修改Snowy源码头部的版权声明。
3.请保留源码和相关描述文件的项目出处，作者声明等。
4.分发源码时候，请注明软件出处 https://gitee.com/xiaonuobase/snowy
5.在修改包名，模块名称，项目代码等时，请注明软件出处 https://gitee.com/xiaonuobase/snowy
6.若您的项目无法满足以上几点，可申请商业授权，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.modular.suppsort.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.core.consts.SymbolConstant;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.factory.PageFactory;
import vip.xiaonuo.core.factory.TreeBuildFactory;
import vip.xiaonuo.core.pojo.node.AntdBaseTreeNode;
import vip.xiaonuo.core.pojo.page.PageResult;
import vip.xiaonuo.core.util.PoiUtil;
import vip.xiaonuo.modular.suppdata.entity.SuppData;
import vip.xiaonuo.modular.suppdata.service.SuppDataService;
import vip.xiaonuo.modular.suppsort.entity.SuppSort;
import vip.xiaonuo.modular.suppsort.enums.SuppSortExceptionEnum;
import vip.xiaonuo.modular.suppsort.mapper.SuppSortMapper;
import vip.xiaonuo.modular.suppsort.param.SuppSortParam;
import vip.xiaonuo.modular.suppsort.service.SuppSortService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 供应商分类service接口实现类
 *
 * @author zjk
 * @date 2022-08-04 13:41:54
 */
@Service
public class SuppSortServiceImpl extends ServiceImpl<SuppSortMapper, SuppSort> implements SuppSortService {
    @Resource
    SuppDataService suppDataService;

    @Override
    public PageResult<SuppSort> page(SuppSortParam suppSortParam) {
        QueryWrapper<SuppSort> queryWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotNull(suppSortParam)) {

//            // 根据父类id 查询
//            if (ObjectUtil.isNotEmpty(suppSortParam.getPid())) {
//                queryWrapper.lambda().eq(SuppSort::getPid, suppSortParam.getPid());
//            }
//            // 根据父类id集合 查询
//            if (ObjectUtil.isNotEmpty(suppSortParam.getPids())) {
//                queryWrapper.lambda().eq(SuppSort::getPids, suppSortParam.getPids());
        // 根据供应商分类名称 查询
        if (ObjectUtil.isNotEmpty(suppSortParam.getSortName())) {
            queryWrapper.lambda().like(SuppSort::getSortName, suppSortParam.getSortName());
        }
        // 根据备注 查询
        if (ObjectUtil.isNotEmpty(suppSortParam.getRemark())) {
            queryWrapper.lambda().like(SuppSort::getRemark, suppSortParam.getRemark());
        }
        //根据父级查询
        if (ObjectUtil.isNotEmpty(suppSortParam.getPid())) {
            queryWrapper.nested(item -> {
                //查询包括自身,Pid为自身id
                item.lambda().eq(SuppSort::getId, suppSortParam.getPid()).
                        or().like(SuppSort::getPids, suppSortParam.getPid());
            });
            }
        }
        queryWrapper.orderByDesc("create_time");
        return new PageResult<>(this.page(PageFactory.defaultPage(), queryWrapper));
    }

    @Override
    public List<SuppSort> list(SuppSortParam suppSortParam) {
        return this.list();
    }

    @Override
    public void add(SuppSortParam suppSortParam) {
        SuppSort suppSort = new SuppSort();
        BeanUtil.copyProperties(suppSortParam, suppSort);
        //校验参数
        checkParam(suppSortParam, false);
        this.fillPids(suppSort);
        this.save(suppSort);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<SuppSortParam> suppSortParamList) {
        List<Long> suppSortIds =new ArrayList<>();
        suppSortParamList.forEach(suppSortParam -> {
            //调用方法
            SuppSort suppSort = this.querySuppSort(suppSortParam);
            Long id = suppSort.getId();
            //节点id获取子节点id
            List<Long> childIdList = this.getChildIdListById(id);
            //如果该客户类型下存在子类型，则不可删除
            if (childIdList.size() >= 1) {
                throw new ServiceException(7, " [" + suppSort.getSortName() + "] 存在子类型不可删除!");
            } else {
                QueryWrapper<SuppData> queryWrapper = new QueryWrapper<>();
                //根据供应商id查客户表
                if (ObjectUtil.isNotEmpty(id)) {
                    queryWrapper.lambda().eq(SuppData::getSuppSortId, id);
                }
                List<SuppData> suppDatasList = suppDataService.list(queryWrapper);
                //如果客户类型下存在客户，则不可删除
                if (suppDatasList.size() >= 1) {
                    throw new ServiceException(8, " [" + suppSort.getSortName() + "] 存在所属客户,不可删除!");
                }
            }
            suppSortIds.add(suppSortParam.getId());
        });
        this.removeByIds(suppSortIds);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SuppSortParam suppSortParam) {
        //调用方法，根据id查询当前产品类型数据
        SuppSort suppSort = this.querySuppSort(suppSortParam);
        //校验参数
        checkParam(suppSortParam, true);
        BeanUtil.copyProperties(suppSortParam, suppSort);
        this.fillPids(suppSort);
        //更新子的父id
        List<Long> childIdListById = this.getChildIdListById(suppSort.getId());
        childIdListById.forEach(subChildId -> {
            SuppSort child = this.getById(subChildId);
            SuppSortParam childParam = new SuppSortParam();
            BeanUtil.copyProperties(child, childParam);
            this.edit(childParam);
        });
        this.updateById(suppSort);
    }

    @Override
    public SuppSort detail(SuppSortParam suppSortParam) {
        return this.querySuppSort(suppSortParam);
    }

    /**
     * 校验参数，检查是否存在相同的名称和编码
     *
     * @author zjk
     * @date 2022-08-04 13:41:54
     */
    private void checkParam(SuppSortParam suppSortParam, boolean isExcludeSelf) {
        Long id = suppSortParam.getId();
        String name = suppSortParam.getSortName();
        Long pid = suppSortParam.getPid();

        //如果父id不是根节点
        if (!pid.equals(0L)) {
            SuppSort suppSort = this.getById(pid);
            if (ObjectUtil.isNull(suppSort)) {
                //父机构不在
                throw new ServiceException(SuppSortExceptionEnum.ORG_NOT_EXIST);
            }
        }

        // isExcludeSelf为true代表是编辑，父id和自己的id不能一致
        if (isExcludeSelf) {
            if (suppSortParam.getId().equals(suppSortParam.getPid())) {
                throw new ServiceException(SuppSortExceptionEnum.ID_CANT_EQ_PID);
            }

            // 如果是编辑，父id不能为自己的子节点
            List<Long> childIdListById = this.getChildIdListById(suppSortParam.getId());
            if (ObjectUtil.isNotEmpty(childIdListById)) {
                if (childIdListById.contains(suppSortParam.getPid())) {
                    throw new ServiceException(SuppSortExceptionEnum.PID_CANT_EQ_CHILD_ID);
                }
            }
        }
        LambdaQueryWrapper<SuppSort> queryWrapperByName = new LambdaQueryWrapper<>();
        queryWrapperByName.eq(SuppSort::getSortName, name);

        if (isExcludeSelf) {
            queryWrapperByName.ne(SuppSort::getId, id);
        }
        int countByName = this.count(queryWrapperByName);

        if (countByName >= 1) {
            throw new ServiceException(SuppSortExceptionEnum.ORG_NAME_REPEAT);
        }
    }

    /**
     * 获取供应商分类
     *
     * @author zjk
     * @date 2022-08-04 13:41:54
     */
    private SuppSort querySuppSort(SuppSortParam suppSortParam) {
        SuppSort suppSort = this.getById(suppSortParam.getId());
        if (ObjectUtil.isNull(suppSort)) {
            throw new ServiceException(SuppSortExceptionEnum.NOT_EXIST);
        }
        return suppSort;
    }

    @Override
    public void export(SuppSortParam suppSortParam) {
        List<SuppSort> list = this.list(suppSortParam);
        PoiUtil.exportExcelWithStream("SnowySuppSort.xls", SuppSort.class, list);
    }

    /**
     * 获取组织机构树
     */
    @Override
    public List<AntdBaseTreeNode> tree(SuppSortParam suppSortParam) {
        List<AntdBaseTreeNode> treeNodeList = CollectionUtil.newArrayList();
        //按AntdBaseTreeNode要求构建树形的数据结构
        this.list().forEach(SuppSort -> {
            AntdBaseTreeNode proTreeNode = new AntdBaseTreeNode();
            proTreeNode.setId(SuppSort.getId());
            proTreeNode.setParentId(SuppSort.getPid());
            proTreeNode.setTitle(SuppSort.getSortName());
            proTreeNode.setValue(String.valueOf(SuppSort.getId()));
            treeNodeList.add(proTreeNode);
        });
        return new TreeBuildFactory<AntdBaseTreeNode>().doTreeBuild(treeNodeList);
    }

    /**
     * 填充父ids
     */
    private void fillPids(SuppSort suppSort) {
        if (suppSort.getPid().equals(0L)) {
            suppSort.setPids(SymbolConstant.LEFT_SQUARE_BRACKETS +
                    0 +
                    SymbolConstant.RIGHT_ANGLE_BRACKETS +
                    SymbolConstant.COMMA);
        } else {
            //获取父类型数据
            SuppSort suppSort1 = this.getById(suppSort.getPid());
            //将父类型的所有父类中拼接上自身的id，即为当前添加类型的所有父类
            suppSort.setPids(suppSort1.getPids() +
                    SymbolConstant.LEFT_SQUARE_BRACKETS + suppSort1.getId() +
                    SymbolConstant.RIGHT_SQUARE_BRACKETS +
                    SymbolConstant.COMMA);
        }
    }
    /**
     * 根据节点id获取所有子节点id集合
     */
    @Override
    public List<Long> getChildIdListById(Long id) {
        List<Long> childIdList = CollectionUtil.newArrayList();
        LambdaQueryWrapper<SuppSort> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(SuppSort::getPids, SymbolConstant.LEFT_SQUARE_BRACKETS + id +
                SymbolConstant.RIGHT_SQUARE_BRACKETS);
        this.list(queryWrapper).forEach(suppSort -> childIdList.add(suppSort.getId()));
        return childIdList;
    }

}